
package com.joolun.cloud.pay.api.controller.wx;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.joolun.cloud.common.core.util.R;
import com.joolun.cloud.common.security.annotation.Inside;
import com.joolun.cloud.pay.api.config.WxPayConfiguration;
import com.joolun.cloud.pay.api.service.PayConfigService;
import com.joolun.cloud.pay.common.constant.PayConstants;
import com.joolun.cloud.pay.common.entity.PayConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 微信支付
 *
 * @author www.joolun.com
 * @date 2019-03-23 21:26:35
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/wxpay")
@Api(value = "wxpay", tags = "微信支付")
public class WxPayController {

	private final PayConfigService payConfigService;

	/**
	 * 调用统一下单接口，并组装生成支付所需参数对象.
	 *
	 * @param request 统一下单请求参数
	 * @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
	 */
	@ApiOperation(value = "调用统一下单接口")
	@Inside
	@PostMapping("/unifiedOrder")
	public R unifiedOrder(@RequestBody WxPayUnifiedOrderRequest request) {
		WxPayConfig wxPayConfig = new WxPayConfig();
		wxPayConfig.setSubMchId(request.getSubMchId());
		WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
		try {
			if("APP".equals(request.getTradeType())){//trade_type=APP时
				PayConfig payConfig = payConfigService.getOne(Wrappers.<PayConfig>query().lambda()
						.eq(PayConfig::getType, PayConstants.PAY_TYPE_1));
				request.setSubAppId(payConfig.getSubAppId());
			}
			if("NATIVE".equals(request.getTradeType())){//trade_type=NATIVE时
				request.setProductId(request.getOutTradeNo());
			}
			return R.ok(wxPayService.createOrder(request));
		} catch (WxPayException e) {
			if("INVALID_REQUEST".equals(e.getErrCode())){
				return R.failed("订单号重复，请重新下单");
			}
			e.printStackTrace();
			return R.failed(e.getReturnMsg() + "" + e.getCustomErrorMsg() + "" + e.getErrCodeDes());
		}
	}

	/**
	 * 处理支付回调
	 * @param xmlData
	 * @return
	 */
	@ApiOperation(value = "处理支付回调")
	@Inside
	@PostMapping("/notifyOrder")
	public R notifyOrder(@RequestBody String xmlData) {
		WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
//		String appId = rs.getAppid();
		String SubMchId = rs.getSubMchId();
		WxPayConfig wxPayConfig = new WxPayConfig();
//		wxPayConfig.setAppId(appId);
		wxPayConfig.setSubMchId(SubMchId);
		WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
		try {
			WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
			return R.ok(notifyResult);
		} catch (WxPayException e) {
			e.printStackTrace();
			return R.failed(e.getErrCodeDes());
		}
	}

	/**
	 * <pre>
	 * 微信支付-申请退款.
	 * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
	 * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/refund
	 * </pre>
	 *
	 * @param request 请求对象
	 * @return 退款操作结果 wx pay refund result
	 * @throws WxPayException the wx pay exception
	 */
	@ApiOperation(value = "申请退款")
	@Inside
	@PostMapping("/refundOrder")
	public R refundOrder(@RequestBody WxPayRefundRequest request) {
		WxPayConfig wxPayConfig = new WxPayConfig();
		wxPayConfig.setAppId(request.getAppid());
		wxPayConfig.setSubMchId(request.getSubMchId());
		WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
		try {
			return R.ok(wxPayService.refund(request));
		} catch (WxPayException e) {
			e.printStackTrace();
			return R.failed(e.getCustomErrorMsg());
		}
	}

	/**
	 * 处理退款回调
	 * @param xmlData
	 * @return
	 */
	@ApiOperation(value = "处理退款回调")
	@Inside
	@PostMapping("/notifyRefunds")
	public R notifyRefunds(@RequestBody String xmlData) {
		WxPayOrderNotifyResult rs = WxPayOrderNotifyResult.fromXML(xmlData);
		String appId = rs.getAppid();
		String SubMchId = rs.getSubMchId();
		WxPayConfig wxPayConfig = new WxPayConfig();
		wxPayConfig.setAppId(appId);
		wxPayConfig.setSubMchId(SubMchId);
		WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
		try {
			WxPayRefundNotifyResult notifyResult = wxPayService.parseRefundNotifyResult(xmlData);
			return R.ok(notifyResult);
		} catch (WxPayException e) {
			e.printStackTrace();
			return R.failed(e.getErrCodeDes());
		}
	}

	/**
	 * 查询订单
	 * @param request
	 * @return
	 */
	@ApiOperation(value = "查询订单")
	@Inside
	@PostMapping("/queryOrder")
	public R queryOrder(@RequestBody WxPayOrderQueryRequest request) {
		WxPayConfig wxPayConfig = new WxPayConfig();
		wxPayConfig.setAppId(request.getAppid());
		wxPayConfig.setSubMchId(request.getSubMchId());
		WxPayService wxPayService = WxPayConfiguration.getPayService(wxPayConfig);
		try {
			WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder(request);
			return R.ok(wxPayOrderQueryResult);
		} catch (WxPayException e) {
			return R.failed(e.getErrCodeDes());
		}
	}
}
